home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* */
- /* INTHOOK.C: Sample application to illustrate interrupt hooking under */
- /* Windows 3.0 using DPMI 0.9 services */
- /* */
- /* Written by Walter Oney */
- /* Requires Microsoft C 6.0A */
- /* */
- /****************************************************************************/
-
- /* Include files */
- #include "windows.h" /* MS windows dcls */
- #include "dos.h" /* for FP_SEG, FP_OFF */
-
- /* Local procedures and data */
- static HANDLE hInst ; /* current instance handle */
- static HWND hMyWindow ; /* handle for our window */
- static void (interrupt far *org60)() ; /* original INT 60 handler */
- static void (far *callback)() ; /* real mode callback address */
- typedef struct
- { /* real mode callback */
- unsigned long edi, esi, ebp, junk, ebx, edx, ecx, eax ;
- unsigned short flags, es, ds, fs, gs, ip, cs, sp, ss ;
- } CBSTRUCT ; /* real mode callback */
- CBSTRUCT cb60 ; /* callback for INT 60 handling */
-
- static void hook60(void) ; /* hook INT 60 */
- static void unhook60(void) ; /* unhook INT 60 */
- static void interrupt far int60() ; /* interrupt handler */
-
- /**********************************************************************/
-
- /* Main window procedure: */
-
- LONG FAR PASCAL MainWndProc
- (HWND hWnd, /* window handle */
- WORD iMessage, /* message code */
- WORD wParam, /* 1st parameter */
- LONG lParam) /* 2d parameter */
- { /* MainWndProc */
-
- /* Local variables */
- long retcode = 0 ; /* return code */
-
- /* Text */
- switch(iMessage)
- { /* process message */
-
- case WM_CREATE:
- hMyWindow = hWnd ; /* so INT60 can find it */
- hook60() ;
- break ;
-
- case WM_USER: /* posted by int60() */
- MessageBox(GetFocus(), "Wake up!", "Salutations",
- MB_ICONEXCLAMATION | MB_OK) ;
- break ;
-
- case WM_DESTROY: /* window being destroyed */
- unhook60() ;
- PostQuitMessage(0) ;
- break ;
-
- default: /* some other message */
- retcode = DefWindowProc(hWnd, iMessage, wParam, lParam) ;
- break ;
- } /* process message */
- return retcode ;
- } /* MainWndProc */
-
- /**********************************************************************/
-
- /* Window message loop: */
-
- int PASCAL WinMain
- (HANDLE hInstance, /* current instance */
- HANDLE hPrevInstance, /* previous instance (if any) */
- LPSTR lpCmdLine, /* command line */
- int nCmdShow) /* show window type (open/icon) */
- { /* WinMain */
-
- /* Local variables */
- HWND hWnd ; /* window handle */
- MSG msg ; /* current message */
- WNDCLASS wc ; /* template for this class */
-
- /* Text */
-
- /* Only allow one instance of the application at a time -- there's only
- one interrupt vector to hook! */
- if (hPrevInstance)
- return FALSE ;
-
- /* Create the window class. */
- wc.style = 0 ; /* default styles */
- wc.lpfnWndProc = MainWndProc ; /* window proc */
- wc.cbClsExtra = 0 ; /* no extra bytes for class */
- wc.cbWndExtra = 0 ; /* no extra bytes for instance */
- wc.hInstance = hInstance ; /* who created the class */
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION) ;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW) ; /* default cursor */
- wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH) ;
- wc.lpszMenuName = NULL ; /* no menu */
- wc.lpszClassName = "AppWClass" ; /* name of window class */
- if (!RegisterClass(&wc))
- return FALSE ;
-
- /* Create an instance of the class (i.e., our own window) */
- hInst = hInstance ; /* so window proc can access it */
- hWnd = CreateWindow("AppWClass",
- "Interrupt Hook Sample Application",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL) ;
- if (!hWnd)
- return FALSE ;
- ShowWindow(hWnd, SW_SHOWMINIMIZED) ;
- UpdateWindow(hWnd) ;
-
- /* Main message loop */
- while (GetMessage(&msg, NULL, NULL, NULL))
- { /* until WM_QUIT message */
- TranslateMessage(&msg) ; /* xlate virtual key codes */
- DispatchMessage(&msg) ; /* dispatch handler */
- } /* until WM_QUIT message */
- return msg.wParam ; /* PostQuitMessage's arg */
- } /* WinMain */
-
- /**********************************************************************/
-
- /* HOOK60 hooks software interrupt 60h in real mode, using a real-mode
- callback to get control passed to int60(). */
-
- static void hook60()
- { /* hook60 */
- _asm
- {
- push ds ; save DS across call
-
- mov ax, ds ; ES:DI -> callback structure
- mov es, ax ; ..
- mov di, offset cb60; ..
- mov ax, cs ; DS:SI -> routine to call
- mov ds, ax ; ..
- mov si, offset int60 ; ..
- mov ax, 0303h ; fcn 0303: allocate real mode callback
- int 31h ; issue DPMI function request
-
- pop ds ; restore DS
- mov callback, dx ; CX:DX = callback address
- mov callback+2, cx ; ..
-
- mov bl, 60h ; BL = interrupt number (60h)
- mov ax, 0200h ; fcn 0200: get real mode interrupt vector
- int 31h ; issue DPMI function request
- mov org60, dx ; CX:DX = original real mode vector
- mov org60+2, cx ; ..
-
- mov dx, callback ; CX:DX = new REAL MODE handler address
- mov cx, callback+2 ; ..
- mov ax, 0201h ; fcn 0201: set real mode interrupt vector
- int 31h ; issue DPMI fcn request
- }
- } /* hook60 */
-
- /**********************************************************************/
-
- /* UNHOOK60 restores the original interrupt 60h vector. */
-
- static void unhook60()
- { /* unhook60 */
- _asm
- {
- mov dx, org60 ; CX:DX = original INT 60 vector
- mov cx, org60+2 ; ..
- mov bl, 60h ; BL = interrupt number (60h)
- mov ax, 0201h ; fcn 0201: set real mode interrupt vector
- int 31h ; issue DPMI fcn request
-
- mov dx, callback ; CX:DX = real-mode callback address
- mov cx, callback+2 ; ..
- mov ax, 0304h ; fcn 0304: free real mode callback
- int 31h ; issue DPMI fcn request
- }
- } /* unhook60 */
-
- /**********************************************************************/
-
- /* INT60 is the interrupt handler for interrupt 60h. It gains control from
- the real-mode callback address allocated by HOOK60() and uses PostMessage
- to send a message to the application's window procedure. */
-
- typedef struct
- { /* interrupt register structure */
- unsigned short es, ds ;
- unsigned short di, si, bp, sp, bx, dx, cx, ax ;
- unsigned short flags, ip, cs ;
- } IFRAME ; /* interrupt register structure */
-
- static void interrupt far int60(IFRAME f)
- { /* int60 */
- unsigned int far *isp ; /* interrupting stack pointer */
-
- /* Simulate IRET in signalling process. */
- FP_SEG(isp) = f.ds ;
- FP_OFF(isp) = f.si ;
- cb60.ip = isp[0] ;
- cb60.cs = isp[1] ;
- cb60.flags = isp[2] ;
- cb60.sp += 6 ;
-
- /* Post a private message leading to a message box. */
- PostMessage(hMyWindow, WM_USER, NULL, NULL) ;
- } /* int60 */